#pragma once

#include <complex>
#include <vector>

namespace cem
{

class ParameterReader;
class ElectromagneticsSystem;
struct BoundarySpec;

// SolverManager 负责求解器配置与求解流程（脚手架阶段不接入 PETSc）。
class SolverManager
{
public:
    // 函数: configure_from_parameters
    // 作用: 依据参数进行求解器配置（占位）。
    // 参数: params - 参数读取器
    // 返回: 无
    void configure_from_parameters(const ParameterReader & params);

    // 函数: solve
    // 作用: 对系统执行求解（占位）。
    // 参数: system - 电磁系统引用
    // 返回: 无
    void solve(ElectromagneticsSystem & system);

    // 函数: solve_dual_polarizations_reuse_matrix
    // 作用: 在同一套已装配矩阵上，针对两组“极化方向不同但类型一致”的边界规格
    //       生成两份右端项并复用同一线性求解器/预条件器进行两次回代，
    //       从而避免重复装配/预处理，近似达到“保留因子分解”的效果。
    // 假设:
    //   1) system 在外部已通过 initialize() 构建，且其 boundary_specs() 对应第1套极化（如 Ex）。
    //   2) 第1套极化已用于装配矩阵（调用者可先行调用 Assembler::assemble(system)）。
    //      若未装配，本函数会先装配一次矩阵与第1套 RHS。
    //   3) 两套极化仅在方向/幅值上不同，边界类型与 id 集相同；
    //      这样矩阵的零行(Dirichlet)集合保持一致，保证矩阵可在两次回代中复用。
    // 参数:
    //   system        - 电磁系统（持有矩阵/向量/网格/材料）
    //   specs_pol1    - 第1套极化用的边界规格（通常与 system.initialize 时一致）
    //   specs_pol2    - 第2套极化用的边界规格（仅方向/幅值不同）
    //   out_sol_pol1  - 输出: 第1套极化解（按全局顺序，本函数在 rank 0 聚合）
    //   out_sol_pol2  - 输出: 第2套极化解（按全局顺序，本函数在 rank 0 聚合）
    // 返回: 无
    void solve_dual_polarizations_reuse_matrix(ElectromagneticsSystem & system,
                                               const std::vector<BoundarySpec> & specs_pol1,
                                               const std::vector<BoundarySpec> & specs_pol2,
                                               std::vector<std::complex<double>> & out_sol_pol1,
                                               std::vector<std::complex<double>> & out_sol_pol2);
};

} // namespace cem